<template>
  <div class="upload-container">
    <!-- 顶部导航栏 -->
    <el-menu
      :default-active="activeIndex"
      class="el-menu-demo"
      mode="horizontal"
      @select="handleSelect"
    >
      <el-menu-item index="1" class="nav-item">
        <el-icon><HomeFilled /></el-icon>
        <span>主页</span>
      </el-menu-item>
      <el-menu-item index="2" class="nav-item">
        <el-icon><PictureFilled /></el-icon>
        <span>图片</span>
      </el-menu-item>
      <el-menu-item index="3" class="nav-item">
        <el-icon><VideoCameraFilled /></el-icon>
        <span>视频</span>
      </el-menu-item>
      <el-menu-item index="4" class="nav-item">
        <el-icon><UploadFilled /></el-icon>
        <span>上传</span>
      </el-menu-item>
    </el-menu>

    <!-- 顶部间距 -->
    <div class="h-6" />

    <!-- 上传区域 -->
    <div class="upload-section">
      <div class="section-title">
        <el-icon><Upload /></el-icon>
        <span>文件上传</span>
      </div>

      <el-form
        ref="uploadFormRef"
        :model="uploadForm"
        :rules="rules"
        label-width="100px"
        class="upload-form"
        :validate-on-rule-change="false"
        :validate-on-input="true"
      >
        <el-form-item label="文件" prop="file">
          <el-upload
            class="upload-dragger"
            drag
            action="#"
            :auto-upload="false"
            :on-change="handleFileChange"
            :limit="1"
            :file-list="fileList"
            :on-remove="handleRemove"
          >
            <el-icon class="el-icon--upload"><upload-filled /></el-icon>
            <div class="el-upload__text">
              将文件拖到此处，或<em>点击上传</em>
            </div>
            <template #tip>
              <div class="el-upload__tip">
                仅支持上传单个文件，支持图片或视频
              </div>
            </template>
          </el-upload>
        </el-form-item>

        <!-- 视频预览及封面选择 -->
        <el-form-item
          v-if="uploadForm.type === 'video' && uploadForm.file"
          label="选择封面"
        >
          <div>
            <video
              :src="videoPreviewUrl"
              controls
              style="max-width: 100%; margin-bottom: 12px; border-radius: 8px"
            ></video>

            <div
              class="thumb-container"
              style="display: flex; flex-wrap: wrap; gap: 8px"
            >
              <div
                v-for="(thumb, index) in thumbnails"
                :key="index"
                class="thumb"
                :style="{
                  border:
                    thumb === selectedCover
                      ? '3px solid #409eff'
                      : '1px solid #dcdfe6',
                  borderRadius: '4px',
                  cursor: 'pointer',
                }"
                @click="selectedCover = thumb"
              >
                <img :src="thumb" style="height: 80px; object-fit: cover" />
              </div>
            </div>
          </div>
        </el-form-item>

        <el-form-item label="标题" prop="title">
          <el-input v-model="uploadForm.title" placeholder="请输入文件标题" />
        </el-form-item>

        <el-form-item label="类型" prop="type">
          <el-select v-model="uploadForm.type" placeholder="请选择文件类型">
            <el-option label="图片" value="image" />
            <el-option label="视频" value="video" />
          </el-select>
        </el-form-item>

        <el-form-item label="描述" prop="description">
          <el-input
            v-model="uploadForm.description"
            type="textarea"
            :rows="3"
            placeholder="请输入文件描述"
          />
        </el-form-item>

        <el-form-item label="设为轮播图" prop="isBanner">
          <el-switch
            v-model="uploadForm.isBanner"
            :disabled="uploadForm.type === 'video'"
          />
        </el-form-item>

        <el-form-item>
          <el-button type="primary" @click="submitUpload" :loading="uploading">
            上传
          </el-button>
          <el-button @click="resetForm">重置</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, watch, onMounted, nextTick } from "vue";
import { useRouter } from "vue-router";
import { ElMessage } from "element-plus";
import useUserInfoStore from "@/stores/userInfo";
import {
  PictureFilled,
  VideoCameraFilled,
  HomeFilled,
  Edit,
  Upload,
  UploadFilled,
} from "@element-plus/icons-vue";
import { upload } from "@/api/upload.js";

const router = useRouter();
const activeIndex = ref("2");
const uploading = ref(false);
const uploadFormRef = ref();
const videoPreviewUrl = ref(""); // 视频预览 URL
const thumbnails = ref([]); // 截图帧图列表
const selectedCover = ref(""); // 用户选择的封面 base64 图

const uploadForm = reactive({
  file: null,
  title: "",
  type: "image", // 默认图片
  isBanner: false,
  description: "",
  createId: "",
});

const fileList = ref([]);
const userInfoStore = useUserInfoStore();

const rules = {
  file: [{ required: true, message: "请选择要上传的文件", trigger: "change" }],
  title: [{ required: true, message: "请输入文件标题", trigger: "input" }],
  type: [{ required: true, message: "请选择文件类型", trigger: "change" }],
  description: [
    { required: true, message: "请输入文件描述", trigger: "input" },
  ],
};

const handleSelect = (key) => {
  const routes = ["/daily", "/picture", "/video", "/upload"];
  router.push(routes[parseInt(key) - 1]);
};

const handleFileChange = async (uploadFile, fileListVal) => {
  if (uploadFile.raw) {
    uploadForm.file = uploadFile.raw;
    fileList.value = [uploadFile];

    // 根据文件类型自动设置类型
    if (uploadFile.raw.type.startsWith("video/")) {
      uploadForm.type = "video";
      uploadForm.isBanner = false; // 视频类型强制设置 isBanner 为 false
      const url = URL.createObjectURL(uploadFile.raw);
      videoPreviewUrl.value = url;
      await nextTick();
      extractThumbnails(url);
    } else if (uploadFile.raw.type.startsWith("image/")) {
      uploadForm.type = "image";
      videoPreviewUrl.value = "";
      thumbnails.value = [];
      selectedCover.value = "";
    } else {
      ElMessage.warning("不支持的文件类型");
      handleRemove();
    }
  }
};

const extractThumbnails = (url) => {
  const video = document.createElement("video");
  video.src = url;
  video.crossOrigin = "anonymous";

  video.addEventListener("loadedmetadata", async () => {
    const duration = Math.min(10, video.duration); // 前10秒
    const interval = 1; // 每秒1帧
    thumbnails.value = [];

    for (let i = 0; i < duration; i += interval) {
      await new Promise((resolve) => {
        video.currentTime = i;
        video.onseeked = () => {
          const canvas = document.createElement("canvas");
          canvas.width = video.videoWidth;
          canvas.height = video.videoHeight;
          const ctx = canvas.getContext("2d");
          ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
          const base64Image = canvas.toDataURL("image/jpeg");
          thumbnails.value.push(base64Image);
          if (i === 0) {
            selectedCover.value = base64Image; // 默认选择第一帧作为封面
          }
          resolve();
        };
      });
    }
  });
};

const handleRemove = () => {
  uploadForm.file = null;
  fileList.value = [];
  videoPreviewUrl.value = "";
  thumbnails.value = [];
  selectedCover.value = "";
};

const submitUpload = async () => {
  if (!uploadFormRef.value) return;

  const userId = userInfoStore.info.id;
  try {
    await uploadFormRef.value.validate();

    // 只在视频上传时检查封面
    if (uploadForm.type === "video" && !selectedCover.value) {
      ElMessage.warning("请选择视频封面图！");
      return;
    }

    uploading.value = true;
    const formData = new FormData();
    formData.append("file", uploadForm.file);
    formData.append("title", uploadForm.title);
    formData.append("type", uploadForm.type);
    formData.append("isBanner", uploadForm.isBanner ? "0" : "1");
    formData.append("description", uploadForm.description);
    formData.append("createId", userId);

    // 只在视频上传时添加封面
    if (uploadForm.type === "video") {
      formData.append("coverImage", selectedCover.value);
    }

    const response = await upload(formData);
    if (response.code === 0) {
      ElMessage.success("上传成功");
      resetForm();
    } else {
      ElMessage.error(response.message || "上传失败");
    }
  } catch (error) {
    console.error("验证失败:", error);
    ElMessage.error("请检查表单填写是否正确");
  } finally {
    uploading.value = false;
  }
};

const resetForm = () => {
  if (!uploadFormRef.value) return;
  uploadFormRef.value.resetFields();
  uploadForm.file = null;
  fileList.value = [];
  videoPreviewUrl.value = "";
  thumbnails.value = [];
  selectedCover.value = "";
};
</script>

<style scoped>
.upload-container {
  min-height: 100vh;
  padding-bottom: 40px;
  background: #f5f7fa;
}

.el-menu--horizontal {
  justify-content: center;
  background: #ffffff;
  border-radius: 8px;
  padding: 0 20px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  border-bottom: none !important;
}

.nav-item {
  position: relative;
  padding: 0 16px;
  color: #303133;
  transition: all 0.3s ease;
  height: 60px;
  line-height: 60px;
}

.nav-item span {
  font-weight: 500;
  font-size: 16px;
  transition: color 0.3s ease;
}

.nav-item .el-icon {
  margin-right: 8px;
  color: #303133;
  transition: transform 0.3s ease, color 0.3s ease;
}

.nav-item:hover,
.nav-item.is-active {
  color: #409eff;
  border-bottom: 2px solid #409eff;
}

.nav-item:hover .el-icon,
.nav-item.is-active .el-icon {
  color: #409eff;
  transform: scale(1.1);
}

.nav-item::after {
  display: none;
}

.upload-section {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
}

.section-title {
  font-size: 22px;
  font-weight: 600;
  color: #303133;
  margin: 40px 0 20px;
  padding-left: 12px;
  border-left: 4px solid #409eff;
  display: flex;
  align-items: center;
  gap: 8px;
}

.upload-form {
  background: #fff;
  padding: 30px;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.upload-dragger {
  width: 100%;
}

.el-upload__tip {
  color: #909399;
  font-size: 12px;
  margin-top: 8px;
}

@media screen and (max-width: 768px) {
  .upload-section {
    padding: 10px;
  }

  .upload-form {
    padding: 20px;
  }
}
</style>
